﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace Xwltz.Framework.Helper
{
    public static class SerializerHelper
    {
        public static string ToJson(this object entity)
        {
            var converter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
            var serializer = new JsonSerializer();
            serializer.Converters.Add(converter);

            var sb = new StringBuilder();
            serializer.Serialize(new JsonTextWriter(new StringWriter(sb)), entity);
            return sb.ToString();
        }

        public static T FromJson<T>(this string json)
        {
            return JsonConvert.DeserializeObject<T>(json);
        }

        public static T TryFromJson<T>(this string json) where T : class, new()
        {
            try
            {
                var value = JsonConvert.DeserializeObject<T>(json);
                return value ?? new T();
            }
            catch (Exception)
            {
                return new T();
            }
        }

        public static object ToJson(this string json)
        {
            return json == null ? null : JsonConvert.DeserializeObject(json);
        }

        public static string ToJson(this object obj, string datetimeformats)
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
            return JsonConvert.SerializeObject(obj, timeConverter);
        }

        public static string ToJson(this object obj, bool ignore)
        {
            if (!ignore)
            {
                return JsonConvert.SerializeObject(obj);
            }
            var jsonSerializerSettings = new JsonSerializerSettings();
            var jsonSerializerSettings2 = jsonSerializerSettings;
            return JsonConvert.SerializeObject(obj, jsonSerializerSettings2);
        }

        public static T ToObject<T>(this string json)
        {
            return json == null ? default(T) : JsonConvert.DeserializeObject<T>(json);
        }

        public static List<T> ToList<T>(this string json)
        {
            return json == null ? null : JsonConvert.DeserializeObject<List<T>>(json);
        }

        public static DataTable ToTable(this string json)
        {
            return json == null ? null : JsonConvert.DeserializeObject<DataTable>(json);
        }

        public static JObject ToJObject(this string json)
        {
            return json == null ? JObject.Parse("{}") : JObject.Parse(json.Replace("&nbsp;", ""));
        }

        public static string ToXml<T>(this T obj)
        {
            var serializer = new XmlSerializer(typeof(T));
            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, obj);
                stream.Position = 0;
                var reader = new StreamReader(stream);
                var xml = reader.ReadToEnd();
                reader.Close();
                return xml;
            }
        }

        public static T FromXml<T>(this string xml)
        {
            var serializer = new XmlSerializer(typeof(T));
            using (var stream = new MemoryStream())
            {
                var writer = new StreamWriter(stream);
                writer.Write(xml);
                writer.Flush();
                stream.Position = 0;
                var instance = (T)serializer.Deserialize(stream);
                writer.Close();
                return instance;
            }
        }

        public static string ToTenPayXml(this SortedDictionary<string, object> dictionary)
        {
            //数据为空时不能转化为xml格式
            if (0 == dictionary.Count) return null;

            var xml = "<xml>";
            foreach (KeyValuePair<string, object> pair in dictionary)
            {
                //字段值不能为null，会影响后续流程
                if (pair.Value == null) return null;

                if (pair.Value is int)
                {
                    xml += "<" + pair.Key + ">" + pair.Value + "</" + pair.Key + ">";
                }
                else if (pair.Value is string)
                {
                    xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
                }
                else 
                {
                    //除了string和int类型不能含有其他数据类型
                    return null;
                }
            }
            xml += "</xml>";
            return xml;
        }

        public static string FromTenPayXml(object returnCode, string returnMsg)
        {
            var dictionary = new SortedDictionary<string, object>
            {
                {"return_code", returnCode}, {"return_msg", returnMsg}
            };
            return dictionary.ToTenPayXml();
        }
    }
}